/* usbUhcdScheduleQSupport.h - scheduling and queueing support for USB UHCD HCD*/

/* Copyright 2004-2005 Wind River Systems, Inc. 

   This software includes software licensed to Wind River Systems, Inc.
   by Wipro, Ltd. Wind River licensees may use this software according  
   to the terms of their Wind River license agreement(s) applicable to 
   this software.
*/

/*
Modification history
--------------------
01d,28mar05,pdg  non-PCI changes
01c,05oct04,mta  SPR100704- Removal of floating point math
01c,05oct04,mta  SPR100704- Removal of floating point math
01b,26jun03,mat  changing the code to WRS standards.
01a,25apr03,ram  written.
*/

/*
DESCRIPTION

This file contains the macros and prototypes of functions used as
supporting functions for the scheduling and queuing operations.
*/

/*
INTERNAL
 *******************************************************************************
 * Filename         : usbUhcdScheduleQSupport.h
 *
 * Copyright        :
 *
 * THE COPYRIGHT IN THE CONTENTS OF THIS SOFTWARE VEST WITH WIPRO
 * LIMITED A COMPANY INCORPORATED UNDER THE LAWS OF INDIA AND HAVING
 * ITS REGISTERED OFFICE AT DODDAKANNELLI SARJAPUR ROAD  BANGALORE
 * 560 035. DISTRIBUTION OR COPYING OF THIS SOFTWARE BY
 * ANY INDIVIDUAL OR ENTITY OTHER THAN THE ADDRESSEE IS STRICTLY
 * PROHIBITED AND MAY INCUR LEGAL LIABILITY. IF YOU ARE NOT THE
 * ADDRESSEE PLEASE NOTIFY US IMMEDIATELY BY PHONE OR BY RETURN EMAIL.
 * THE ADDRESSEE IS ADVISED TO MAINTAIN THE PROPRIETARY INTERESTS OF
 * THIS COPYRIGHT AS PER APPLICABLE LAWS.
 *
 *
 * Description      :  This file contains the macros and prototypes of
 *                     functions used as supporting functions for the
 *                     scheduling and queuing operations.
 *
 *
 */

#ifndef __INCusbUhcdSceduleQSupporth
#define __INCusbUhcdSceduleQSupporth

#ifdef __cplusplus
extern "C" {
#endif

/* includes */

#include "usbOsal.h"

/* defines */

/* mask for endpoint type */

#define USB_UHCD_ATTR_EPTYPE_MASK    0x03
#define USB_UHCD_ATTR_CONTROL        0x00
#define USB_UHCD_ATTR_ISOCHRO        0x01
#define USB_UHCD_ATTR_BULK           0x02
#define USB_UHCD_ATTR_INTERRUPT      0x03

/* Values for checking the interrupt mask value */
#define USB_UHCD_IOSP_ENABLE         0x08
#define USB_UHCD_IOC_ENABLE          0x04
#define USB_UHCD_IORESUME_ENABLE     0x02
#define USB_UHCD_IOCRC_ENABLE        0x01

#define USB_UHCD_IOSP_ENABLE_BIT         0x03
#define USB_UHCD_IOC_ENABLE_BIT          0x02
#define USB_UHCD_IORESUME_ENABLE_BIT     0x01
#define USB_UHCD_IOCRC_ENABLE_BIT        0x00
/*
 * Value set by the software before the TD is being placed on the list to be
 * processed by the HC
 */
#define USB_UHCD_NOT_ACCESSED         15

/* UHCD HCD specific status - Start */

#define USB_UHCD_BABBLE               91     /* Babble error */

#define USB_UHCD_NAK                  92     /* The transfer has NAK */

#define USB_UHCD_TIMEOUT              93     /* Timeout error */

#define USB_UHCD_BITSTUFF             94     /* Bitstuff error */

/* UHCD HCD specific status - End */

#define USB_UHCD_SAFETY_MARGIN        100    /* Safety margin value */

#define USB_UHCD_NINETY_PERCENT_BW    900000 /* Value indicating 90 */
                                             /* % of the bandwidth */

#define USB_UHCD_BW                   1000000 /* Value indicating 100 % */
                                              /* of the bandwidth */

#define USB_UHCD_HOST_DELAY           1000    /* Delay value used for */
                                              /* calculating the bus time */

/* Margin value for adding to the periodic frame list */

#define USB_UHCD_PERIODIC_LIST_MODIFICATION_MARGIN   4

/* The Window size allowed for adding an set of Isoc TDs */
#define USB_UHCD_PERIODIC_LIST_WINDOW_SIZE           1024

/* Constants used in bandwidth calculation */
#define usbUhcdBitStuffTime(data)  (7 * 8 * data/6) /* Bit stuff time */


/* PENDING : This might vary for USB 2.0 */

#define USB_UHCD_HOST_DELAY      1000    /* The values are in nanoseconds */
#define USB_UHCD_HUB_LS_SETUP    333

/* typedefs */

/* Data transfer directions */

typedef enum usbUhcdDirection
    {
    BIDIRECTIONAL = 0,          /* No data transfer, applicable in case of
                                 * control */
    DIR_OUT,                    /* Data transfer is from host to device */
    DIR_IN                      /* Data transfer is from device to host */
    } USB_UHCD_DIRECTION;

/* Device speeds */

typedef enum usbUhcdSpeed
    {
    FULL_SPEED,                 /* Full speed */
    LOW_SPEED,                  /* Low speed */
    USB20_HIGH_SPEED            /* High speed */
    } USB_UHCD_SPEED;

/* Pipe types */

typedef enum usbUhcdPipeType
    {
    PIPE_CONTROL,
    PIPE_ISOCHRONOUS,
    PIPE_BULK,
    PIPE_INTERRUPT
    } USB_UHCD_PIPETYPE;


/*******************************************************************************
 * Function Name    : usbUhcdFormEmptyTd
 * Description      : This function forms an empty Transfer Descriptor
 * Parameters       : pipe IN Pointer to the Pipe data structure
 * Return Type      : Pointer to struct uhc_td if TD is created successfully.
 *                    Else NULL.
 ******************************************************************************/

extern USB_UHCD_TD *usbUhcdFormEmptyTd (UINT32 uPipeHandle );

/*******************************************************************************
 * Function Name    : usbUhcdFormEmptyQh
 * Description      : This function forms an empty Queue Head.
 * Parameters       : None.
 * Return Type      : Pointer to struct uhc_qh if QH is created successfully.
 *                    Else NULL
 ******************************************************************************/

extern USB_UHCD_QH *usbUhcdFormEmptyQh (void);

/*******************************************************************************
 * Function Name    : usbUhcdFindLinkForQh
 * Description      : This function is used to find the index of the next node
 *                    in the list.
 * Parameters       : n IN Index of the node element in the tree
 * Return Type      : INT32.
 *                    Returns the index of the next node in the list.
 ******************************************************************************/

extern INT32 usbUhcdFindLinkForQh (INT32 n);

/*******************************************************************************
 * Function Name    : usbUhcdFindQlinkToTree
 * Description      : This function is used to determine the Index into the
 *                    periodic tree which, the Nth entry of the
 *                    frame list must point to. We have a 1024 entries in the
 *                    frame list and a 128 leafed tree. Thus every 128th
 *                    entry of the frame list points to the same point of the
 *                    periodic tree
 * Parameters       : None.
 * Return Type      : INT32.
 *                    Returns the index into the periodic tree which the
 *                    n th entry of the periodic tree will point to.
 ******************************************************************************/

extern INT32 usbUhcdFindQlinkToTree (INT32 n);

/*******************************************************************************
 * Function Name    : usbUhcdFindHcdPipe
 * Description      : This functions is used to locate an HCD pipe structure
 * Parameters       : pipe IN Pointer to the Pipe data structure.
 * Return Type      : Pointer to struct USB_UHCD_HCD_PIPE if the pipe is located.
 *                    NULL otherwise
 ******************************************************************************/

extern USB_UHCD_HCD_PIPE *usbUhcdFindHcdPipe 
         (UINT8 BusIndex, UINT8 deviceNum, UINT8 endPointNum, UINT8 direction, UINT8 type);


/*******************************************************************************
 * Function Name    : usbUhcdFormEmptyPipe
 * Description      : This function is called to create an empty pipe block
 * Parameters       : None.
 * Return Type      : Pointer to USB_UHCD_HCD_PIPE structure if pipe creation is
 *                    successful.
 *                    NULL otherwise.
 ******************************************************************************/

extern USB_UHCD_HCD_PIPE *usbUhcdFormEmptyPipe (void);

/*******************************************************************************
 * Function Name    : usbUhcdLinkQheadBetween
 * Description      : This function is used to link a new Queue Head after
 *                    the existing Queue Head.
 * Parameters       : newQh IN - pointer to the QH to be added.
 *                    presentQh - pointer to the QH after which the new
 *                                 QH is to be added.
 * Return Type      : None
 ******************************************************************************/

extern void usbUhcdLinkQheadBetween(UINT32 uBusIndex,
                                    USB_UHCD_QH *newQh,
                                    USB_UHCD_QH *presentQh);

/*******************************************************************************
 * Function Name    : usbUhcdCalculateBusTime
 * Description      : This function is used to calculate the BW occupied by
 *                    a pipe.
 * Parameters       : speed     IN Speed of the device
 *                    direction IN Direction of the pipe
 *                    pipeType  IN Type of the transfer supported by the pipe
 *                    data      IN Maximum byte count supported by the pipe.
 * Return Type      : INT32
 *                    Returns the calculated bus time in nano seconds
 ******************************************************************************/

extern INT32 usbUhcdCalculateBusTime (UINT8 speed,
                                     UINT8 direction,
                                     UINT8 pipeType,
                                     UINT16 data);

/*******************************************************************************
 * Function Name    : usbUhcdFindTreeBw
 * Description      : This function is used to determine the bandwidth occupied
 *                    by the list of nodes starting from index "treeIndex".
 * Parameter        : treeIndex     IN    Index to the interrupt tree
 *                    usbUhcdTree   IN    Pointer to the list of Periodic Tree 
 * Return Type      : INT32
 *                    Returns the bandwidth occupied by the list.
 * Global Variables : None
 * Calls            : usbUhcdFindLinkForQh ()
 * Called by        : usbUhcdCanIsoBeAccomodated
 *                    usbUhcdFindPosForIntQh
 *                    
 * To Do            : None
 ******************************************************************************/

extern INT32 usbUhcdFindTreeBw(
    INT32     treeIndex,
    USB_UHCD_PERIODIC_TREE  * usbUhcdTree);

/*******************************************************************************
 * Function Name    : UHCD_IsBandwidthAvailable
 * Description      : This function is used to determine whether the bandwidth
 *                    specified as parameter can be accomodated in the
 *                    schedule maintained in the HCD.
 * Parameters       : bw_reqd IN Bandwidth which need to be accomodated.
 * Return Type      : BOOLEAN
 *                    Returns
 *                         TRUE   - if bandwidth is available
 *                         FALSE  - if bandwidth is not available
 ******************************************************************************/
extern USBHST_STATUS usbUhcdIsBandwidthAvailable
                    (UINT8 uBusIndex,
                     UINT8 uDeviceAddress,
                     UINT8 uDeviceSpeed,
                     UCHAR *pCurrentDescriptor,
                     UCHAR *pNewDescriptor);

/*******************************************************************************
 * Function Name    : usbUhcdMaxIsoBwLinkedTo
 * Description      : This function is used to determine the maximum
 *                    bandwidth linked to the isochronous list which is linked
 *                    to the tree node of index 'index'.
 * Parameters       : index         IN Index into the tree. The node in this index
 *                                     should be in the leaf of the tree.
 *                    usbUhcdTable IN Pointer to the list of Periodic Table
 * Return Type      : INT32
 *                    Returns the maximum isochronous bandwidth linked to the
 *                    list
 ******************************************************************************/
extern INT32 usbUhcdMaxIsoBwLinkedTo(
    INT32      index,
    USB_UHCD_PERIODIC_TABLE * usbUhcdTable);

/*******************************************************************************
 * Function Name    : usbUhcdFindPosForIntQh
 * Description      : This function is used to locate a suitable point
 *                    for queueing the interrupt QH based on the bandwidth
 *                    required and the poll rate
 * Parameters       : bwReqd       IN  bandwidth required for the endpoint
 *                    reqPollRate IN  polling rate required for the endpoint.
 *                    list_index    OUT pointer to the variable holding the
 *                                      index of the list to which the QH can
 *                                      be linked.
 *                    usbUhcdTable   IN Pointer to the list of Periodic Table
 *                    usbUhcdTree    IN Pointer to the list of Periodic Tree
 * Return Type      : BOOLEAN
 *                    Returns
 *                       TRUE - if bandwidth can be accomodated for the
 *                              interrupt pipe.
 *                       FALSE - if bandwidth cannot be accomodated for the
 *                               interrupt pipe.
 ******************************************************************************/

extern BOOLEAN usbUhcdFindPosForIntQh(
    INT32 bwReqd,
    UINT reqPollRate,
    INT32 *listIndex,
    USB_UHCD_PERIODIC_TABLE * usbUhcdTable,
    USB_UHCD_PERIODIC_TREE  * usbUhcdTree);

/*******************************************************************************
 * Function Name    : usbUhcdIsLinked
 * Description      : This function is used to determine whether 2 nodes of
 *                    the tree is the part of the same list or not
 * Parameters       : listIndexOuter IN Index of the node with a greater
 *                                        index
 *                    listIndexInner IN Index of the node with a smaller index
 * Return Type      : BOOLEAN
 *                    Returns
 *                        TRUE  - If the nodes are linked.
 *                        FALSE - If the nodes are not linked.
 ******************************************************************************/

extern BOOLEAN usbUhcdIsLinked (INT32 listIndexOuter,
                                INT32 listIndexInner);


/*******************************************************************************
 * Function Name    : usbUhcdMakeTds
 * Description      : This function is used to create the TDs needed for
 *                    a transfer
 * Parameters       : head OUT Pointer holding the pointer to the head of the
 *                             TDs formed.
 *                    tail OUT Pointer holding the pointer to the tail of the
 *                             TDs formed.
 *                    urb  IN  Pointer to the URB.
 *                    toggle IN Toggle value
 * Return Type      : BOOLEAN
 *                    Returns
 *                        TRUE  - If TDs are created successfully.
                          FALSE - If TDs are not created successfully.
 ******************************************************************************/
extern BOOLEAN usbUhcdMakeTds( UINT32      uBusIndex, 
                              USB_UHCD_TD **head,
                              USB_UHCD_TD **tail,
                              USBHST_URB *urb,
                              UINT8 *toggle,
                              USB_UHCD_HCD_PIPE *targetPipe);

/*******************************************************************************
 * Function Name    : usbUhcdFillNonisoStatus
 * Description      : This function is used to fill the status of a
 *                    non isochronous data transfer upon completion.
 * Parameters       : status          IN  Status of the request completion.
 *                    statusInUrb   OUT Pointer to the status of the URB.
 *                    markedForDel  IN  Flag indicating whether it is marked
 *                                        for deletion.
 *                    reqThatHalted IN  Flag indicating whether the request is
 *                                        halted.
 * Return Type      : void
 ******************************************************************************/
extern void usbUhcdFillNonisoStatus (UINT status,
                                     INT8* statusInUrb,
                                     UINT8 markedForDel,
                                     UINT8 reqThatHalted);

/*******************************************************************************
 * Function Name    : usbUhcdFreeTds
 * Description      : This function is used to free up memory allocated
 *                    for a chain of TDs.
 * Parameters       : start          IN  Address of the first TD
 *                    stop           IN  Address of the last TD
 * Return Type      : void
 ******************************************************************************/

extern void usbUhcdFreeTds (USB_UHCD_TD *start, USB_UHCD_TD *stop);

/*******************************************************************************
 * Function Name    : usbUhcdGetTransferLength
 * Description      : This fucntion is used to determine the number of bytes
 *                    actually transfered at the end of a transfer.
 * Parameters       : ni_request IN Pointer to the non isochronous request
 *                                  queue element.
 * Return Type      : UINT
 *                    Returns the number of bytes transferred at the end of the
 *                    transfer
 ******************************************************************************/

extern UINT usbUhcdGetTransferLength
                    (USB_UHCD_NON_ISO_REQUEST_QUEUE *niRequest);

/*******************************************************************************
 * Function Name    : usbUhcdCanIsoBeAccomodated
 * Description      : This function is used to determine whether the
 *                    Isochronous transfer can be accomodated
 * Parameters       : bwReqd         IN bandwidth required
 *                    startIndex     IN Starting index of the list
 *                    maxNumOfItd    IN Maximum number of isochronous TDs
 *                    usbUhcdTable   IN Pointer to the list of Periodic Table
 *                    usbUhcdTree    IN Pointer to the list of Periodic Tree
 * Return Type      : BOOLEAN
 *                    Returns
 *                        TRUE - If isochronous endpoint can be
 *                               accomodated.
 *                        FALSE - If isochronous endpoint cannot be
 *                                accomodated.
 ******************************************************************************/
extern BOOLEAN usbUhcdCanIsoBeAccomodated(
    INT32 bwReqd,
    INT32 startIndex,
    INT32 maxNumOfItd,
    USB_UHCD_PERIODIC_TABLE * usbUhcdTable,
    USB_UHCD_PERIODIC_TREE  * usbUhcdTree);


/*******************************************************************************
 * Function Name    : usbUhcdLinkItds
 * Description      : This function is used to link the isochronous TDs
 *                    to the HC list. This adds each TD to the periodic table.
 * Parameters       : iTd           IN Pointer to the isochronous TD to be
 *                                     linked.
 *                    startIndex   IN Starting index of the list.
 *                    bwReqd       IN Bandwidth required for the transfer.
 * Return Type      : void
 ******************************************************************************/
extern void usbUhcdLinkItds (UINT8 BusIndex,
                             USB_UHCD_TD *iTd,
                             INT32 startIndex);

/*******************************************************************************
 * Function Name    : usbUhcdUnlinkItds
 * Description      : This function is used to unlink and free up the iTDs
 *                    from the periodic table
 * Parameters       : iTd           IN Pointer to the isochronous TD to be
 *                                     linked.
 *                    startIndex   IN Starting index of the list.
 *                    bw            IN Bandwidth required for the transfer.
 * Return Type      : void
 ******************************************************************************/
extern void usbUhcdUnlinkItds (PUHCD_DATA pHCDData, 
                               USB_UHCD_TD *iTd,
                               BOOLEAN freetds);

/*******************************************************************************
 * Function Name    : usbUhcdGetIsoTransferLength
 * Description      : This function is used to get the isochronous transfer
 *                    length.
 * Parameters       : iRequest     IN Pointer to the isochronous request
 *                                     queue.
 * Return Type      : UINT
 *                    Returns the isochronous transfer length
 ******************************************************************************/
extern VOID usbUhcdGetIsoTransferLength 
                        (UINT32                      uBusIndex,         
                         USB_UHCD_ISO_REQUEST_QUEUE *iRequest);


/*******************************************************************************
 * Function Name    : usbUhcdEnterCritical,
 *                    usbUhcdLeaveCritical
 * Description      : This function is called before accessing shared data
 *                    structures to guard them from multiple access.
 ******************************************************************************/

extern void usbUhcdEnterCritical (PUHCD_DATA   pHCDData);
extern void usbUhcdLeaveCritical (PUHCD_DATA   pHCDData);


/*******************************************************************************
 * Function Name    : usbUhcdFillIsoStatus
 * Description      : This function is used to fill the status of a
 *                    Isochronous data transfer upon completion.
 * Parameters       : status          IN  Status of the request completion.
 *                    statusInUrb   OUT Pointer to the status of the URB.
 *                    markedForDel  IN  Flag indicating whether it is marked
 *                                        for deletion.
 *                    reqThatHalted IN  Flag indicating whether the request is
 *                                        halted.
 * Return Type      : void
 * Global Variables : None
 * Calls            : None
 * Called by        : uhc_ProcessCompletedTDs
 * To Do            : None
 ******************************************************************************/

extern VOID usbUhcdFillIsoStatus(UINT32                      uBusIndex,
                                 USBHST_STATUS               status,
                                 pUSBHST_URB                 pUrb,
                                 USB_UHCD_ISO_REQUEST_QUEUE  *iReQ);


/*******************************************************************************
 * Function Name    : usbUhcdProcessIsocTds
 * Description      : This function is used to handle isoc TDs maked for deletion
 * Parameters       : None.
 * Return Type      : void
 * Global Variables : 
 * Calls            : 
 * Called by        : 
 * To Do            : None
 ******************************************************************************/

/***************************************************************************
*
* usbUhcdProcessIsocTds - handles the isoc TDs maked for deletion
*
* RETURNS: N/A
*/

extern VOID usbUhcdProcessIsocTds(PUHCD_DATA pHCDData);


/*******************************************************************************
 * Function Name    : usbUhcdMakeIsocTds
 * Description      : This function is used to create the TDs needed for
 *                    a transfer
 * Parameters       : head OUT Pointer holding the pointer to the head of the
 *                             TDs formed.
 *                    tail OUT Pointer holding the pointer to the tail of the
 *                             TDs formed.
 *                    urb  IN  Pointer to the URB.
 *                    toggle IN Toggle value
 * Return Type      : BOOLEAN
 *                    Returns
 *                        TRUE  - If TDs are created successfully.
                          FALSE - If TDs are not created successfully.
 * Global Variables : None
 * Calls            : usbUhcdFormEmptyTd
 *                    free
 * Called by        : UHCD_SubmitURB
 * To Do            : None
 ******************************************************************************/

/***************************************************************************
*
* usbUhcdMakeIsocTds - create the TDs needed for a transfer
*
* RETURNS: FALSE if TDs are not created successfully.
*/

extern BOOLEAN usbUhcdMakeIsocTds(UINT32      uBusIndex,
                                  USB_UHCD_TD **head,
                                  USB_UHCD_TD **tail,
                                  USBHST_URB *purb,
                                  UINT8 *toggle ,
                                  USB_UHCD_HCD_PIPE *targetPipe);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __INCusbUhcdScheduleQSupporth */


